package practice6;

import java.util.Scanner;

/**
 * 线段树
 */
public class P3372 {
    //节点类
    static class Node{
        int left;   //左边界
        int right;  //右边界
        long value;  //节点值(该区间内数的和)
        long lazy;   //lazy标记,表示子区间更新的增数
    }

    static Node[] tree=new Node[400000];  //线段树
    static long[] num=new long[100000];    //总区间

    //建树
    public static void build(int i,int l,int r){
        tree[i].left=l;
        tree[i].right=r;
        if(l==r){
            tree[i].value=num[r];       //到叶子节点了，返回
            return;
        }
        int mid=(l+r)/2;
        build(i*2,l,mid);
        build(i*2+1,mid+1,r);       //建立左儿子和右儿子
        tree[i].value=tree[i*2].value+tree[i*2+1].value;    //父节点区间和等于左右儿子区间和之和
    }

    //下传懒标记
    public static void pushdown(int i){
        //更新左儿子
        tree[i*2].value+=(tree[i*2].right-tree[i*2].left+1)*tree[i].lazy;
        tree[i*2].lazy=tree[i].lazy;
        //更新右儿子
        tree[i*2+1].value+=(tree[i*2+1].right-tree[i*2+1].left+1)*tree[i].lazy;
        tree[i*2+1].lazy=tree[i].lazy;
        //清除父亲的lazy标记
        tree[i].lazy=0;
    }

    //修改[x,y]区间的值(加k)
    public static void change(int i,int x,int y,long k){
        if(tree[i].left>=x && tree[i].right<=y){
            //该区间被[x,y]完全覆盖,直接更新该节点的值即可
            tree[i].value+=(tree[i].right-tree[i].left+1)*k;
            tree[i].lazy+=k;             //打上lazy标记
            return;
        }
        if(tree[i].lazy!=0){
            //当前区间没被完全覆盖，且有懒标记，则下传懒标记到子节点
            pushdown(i);
        }
        if(tree[i*2].right>=x){
            //与左儿子有交集，更新左儿子的值
            change(i*2,x,y,k);
        }
        if(tree[i*2+1].left<=y){
            //与右儿子有交集，更新右儿子的值
            change(i*2+1,x,y,k);
        }
        tree[i].value=tree[i*2].value+tree[i*2+1].value;    //更新当前节点
    }
    //查询区间[x,y]的和
    public static long search(int i,int x,int y){
        if(tree[i].left>=x && tree[i].right<=y){
            //该区间被[x,y]完全覆盖,直接返回
            return tree[i].value;
        }
        if(tree[i].lazy!=0){
            //当前区间没被完全覆盖，且有懒标记，则下传懒标记到子节点
            pushdown(i);
        }
        long res=0;     //合并左右区间的值
        if(tree[i*2].right>=x){
            //与左儿子有交集，查询左儿子的值
            res+=search(i*2,x,y);
        }
        if(tree[i*2+1].left<=y){
            //与右儿子有交集，查询右儿子的值
            res+=search(i*2+1,x,y);
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        for(int i=0;i<=2*n+1;i++){
            tree[i]=new Node();
        }
        num=new long[n+1];
        for(int i=1;i<=n;i++){
            num[i]=sc.nextLong();
        }
        build(1,1,n);       //建立线段树
        for(int i=0;i<m;i++){
            int type=sc.nextInt();
            int x=sc.nextInt();
            int y=sc.nextInt();
            if(type==1){
                long k=sc.nextLong();
                change(1,x,y,k);    //从根节点开始进行区间修改
            }else{
                long ans=search(1,x,y);      //从更节点开始搜索[x,y]的和
                System.out.println(ans);
            }
        }
    }
}
